Now you have to refine the new action for chosing the Create view and the searching action for chosing the Update view. First, define your own controller, in your controllers.xml, thus:
<controllername="MyTypical"><actionname="new"class="com.mycompany.myapplication.actions.MyNewAction"image="images/new.gif"on-init="true"keystroke="F2"><use-objectname="xava_view"/><!-- Not needed since v4m2 --></action><actionname="search"by-default="if-possible"hidden="true"class="com.mycompany.myapplication.actions.MySearchAction"keystroke="F8"><use-objectname="xava_view"/><!-- Not needed since v4m2 --></action></controller>
And now assign this controller to your module, and define the searching action for the module. Write your module in the application.xml in this way:
And now only remains to refine the logic of your actions. For MySearchAction you write (NOTE: selected entity index values have to be captured (1) so that it might be restored (3) after the reset performed by setViewName(...) method (2)):
How to deactive a property for updating but not for creating?
You have to refine the new action and the searching action. First, define your own controller, in your controllers.xml, thus:
<controllername="MyTypical"><actionname="new"class="com.mycompany.myapplication.actions.MyNewAction"image="images/new.gif"on-init="true"keystroke="F2"><use-objectname="xava_view"/><!-- Not needed since v4m2 --></action><actionname="search"by-default="if-possible"hidden="true"class="com.mycompany.myapplication.actions.MySearchAction"keystroke="F8"><use-objectname="xava_view"/><!-- Not needed since v4m2 --></action></controller>
And now assign this controller to your module, and define the searching action for the module, write your module in the application.xml in this way:
How to access to a property of the model that isn't shown in the view?
From the view you can obtain only the displayed data. But it's possible, using MapFacade class to acess directly to the model.
You can write in your action a code like this one:
publicclass MyAction extends ViewBaseAction {publicvoid execute()throwsException{
Invoice invoice = (Invoice) MapFacade.findEntity(getModelName(), getView().getKeyValues());// Special discount is not shown in the viewBigDecimal specialDiscount = invoice.getSpecialDiscount();
...
}
...
In this way you can access to specialDiscount property although it is not displayed in the current view.
How to modify the appearance of @ReadOnly fields
By default, OpenXava will lightly shade fields that are dropdowns and those annotated with @ReadOnly. Marking a field @ReadOnly also removes the icon associated with editing. However, in my application, a requirement was that read-only fields be highlighted differently. This can be done by adding an entry into your custom.css file in the web/xava/style directory in your project as documented in the Customizing Views section.
The relevant entry is:
input[disabled]{background:red;}
Of course, you can put any valid css that matches your needs.
How to store user preferences (new in v3.0.2)?
Storing user preferences of your application is your business, but for your convenience you can use OpenXava to store user preferences.
OpenXava uses the Java Preferences API for storing and loading user preferences, but adapted for working in a multiuser server environment. You can access to the Preferences object using the Users class of OpenXava. Just in this way:
// Obtain preferences for the current user// and node (an arbitrary category of your choice)Preferences preferences = Users.getCurrentPreferences().node("mynode");// Read a property valueboolean rowsHidden = preferences.getBoolean(ROWS_HIDDEN, false);
...
// Modify and save a property
preferences.putBoolean(ROWS_HIDDEN, rowsHidden);
preferences.flush();
You must call explicitly to flush() in order to store the changed preferences.
Example of basic authentication security for OX application in Tomcat
How to add your own servlets, filters, listeners or resources to your OpenXava application?
For adding your own servlets to your OX application do not modify the web.xml file, instead you can create a servlets.xml (with servlet and servlet-mapping elements), a filters.xml (with filter and filter-mapping elements), a listeners.xml (with listener elements, since v4.0.1) and a resources.xml (with resource-ref elements, since v5.4) in the WEB-INF folder.
For example, if you want to add a servlet called TestServlet, just create a servlets.xml file in WEB-INF with the next content:
This fragment will be automatically inserted in web.xml when you call to deployWar or updateOX ant task.
How to create a new element directly from a @ManyToMany collection? (new in v4m4)
By default in a @ManyToMany collection the user can add existing elements to the collection, however he cannot create new ones. Fortunately, you can add this functionality using the ManyToMany.new action (included in OpenXava) as list action for your collection. As following:
How to change schema, locale and user using url parameters (new in v4m4)
You can change default schema, current locale or current user through web parameters by including the controller UrlParameters(1). For example in application.xml you add the controller:
They are not exclusive, you can use any combination of them.
How to add a second collection in a report
Modify your .jrxml, to add a subreport in one of the available bands (not the details ones, obviously). You can do that easily from the XML perspective of iReport.
You will have to design a new report in iReport describing the fields of the collection you want to add. Generally a columnHeader and a detail band are enough
In your report action, fill in the new parameters:
publicclass MyReportAction extends JasperReportBaseAction {
...
publicMap<String, Object> getParameters()throwsException{
Messages errors = MapFacade.validate("Project", getView().getValues());if(errors.contains())thrownew ValidationException(errors);Map<String, Object> parameters = newHashMap<String, Object>();// fill up the project subreport
parameters.put("subreport_report", JasperCompileManager.compileReport(JRUtils.class.getResourceAsStream("/Project_products.jrxml")));// 1
parameters.put("subreport_ds", new JRBeanCollectionDataSource(getProject().getProducts()));// 2return parameters;}
...
1- Replace by the path to your subreport.
2- Any Collection is valid. The fields of the subreport refer to the properties of the collection members.
How to define a JavaScript-based action?
One use case could be, for example, to be able to click on a button (in a 'detail' page) to execute some custom JavaScript code.
To do so, you need OpenXava version N>=4, and you have to write a IForwardAction whose uri stars with "javascript:"
public class GoToGoogleAction implements IForwardAction {
public String getForwardURI() {
return "javascript:top.location=\"http://www.google.fr\"";
}
public boolean inNewWindow() {
return false;
}
...
}
Other IForwardAction methods could remain empty, or auto-generated if you like.
Since v5.9 you can implements IPostJavaScriptAction, that after the regular action execution executes your JavaScript code:
public class MyJavaScriptAction extends BaseAction implements IJavaScriptPostAction {
public void execute() throws Exception {
addMessage("Hello, I'm Java");
}
public String getPostJavaScript() {
return "alert('Hello, I am JavaScript')";
}
}
Unlike IForwardAction to javascript: in IPostJavaScriptAction the JavaScript is executed when the view is completely updated after regular Java execution.
How to remove PDF + Excel export actions in GUI ?
These actions are defined by the 'Print' controller. All controllers inherits these actions from the default controller, named 'Typical', that extends the 'Print' controller:
But, still, these PDF + Excel export actions remain for collections within a business class. It's due to the 'DefaultListActionsForCollections' controller that extends the 'Print' controller too:
So, in order to remove these PDF + Excel export actions always for embedded collections is to redefine the 'DefaultListActionsForCollections' controller:
How to modify the parameters of the default reports?
We can change the parameters of the default report by code. In this case we change the organization name:
By default this organization name is collected from 'xava.organization' value in the i18n files, but we modify it to that this organization name is collected from a variable value.
Just create a new class that implements to IReportParametersProvider and add the code that you need to the 'getOrganization()' method:
One option is to forward to a JSP that generates the HTML report, you can do it by means of IForwardAction. Another option is using the SimpleHTMLReportAction action (since v4.3) that allows you to work with simple HTML templates.
How to generate several reports from a single action?
Just extend your action from JasperMultipleReportBaseAction (new in v4.3). For an example look at InvoiceTwoReportsAction of OpenXavaTest.
How to merge multiple reports in one PDF?
Just extend your action from JasperConcatReportBaseAction (new in v5.0). Useful when you need to concatenate several reports with different page formats (landscape, portrait). There is an example at MovieReportAction of OpenXavaTest.
How to add your own portlets to your OpenXava application (new in v4.6)?
For adding your own portlets to your OX application do not modify the portlet.xml file, instead you can create a portlet-ext.xml (with portlet elements) and a liferay-display-ext.xml (with portlet elements) in the WEB-INF folder.
For example, if you want to add a portlet called VersionPortlet, just create a portlet-ext.xml file in WEB-INF with the next content:
If you are using Liferay you can optionally create the liferay-display-ext.xml file to add entries to liferay-display.xml file. So, for the above portlet you can write a liferay-display-ext.xml with the next content:
<portletid="Version"/>
This fragment will be automatically inserted in liferay-display.xml when you call to generatePortlets ant task.
Moreover, you have to write the resorce files, in this case you have to write Version_ca.properties, Version_es.properties, Version_en.properties and Version_fr.properties. Here there is a example for Version_en.properties:
javax.portlet.short-title=Version
javax.portlet.title=OpenXavaTest - Version
category.OpenXavaTest=OpenXavaTest
And, of course, you need to write the code for your portlet, in this case:
packageorg.openxava.test.portlets;importjava.io.*;importjavax.portlet.*;importorg.openxava.controller.*;publicclass VersionPortlet extends GenericPortlet {publicvoid doView(RenderRequest request, RenderResponse response)throws PortletException, IOException{
response.setContentType("text/html");
response.getWriter().write("<table border=\"0\">");
writeVersion(response.getWriter(), "The version of OpenXava is", ModuleManager.getVersion());
response.getWriter().write("</table>");}privatevoid writeVersion(PrintWriter out, String unit, String version){
out.write("<tr>");
out.write("<td style=\"padding: 2px 5px 2px 5px;\"><b>" + unit + "</b></td>");
out.write("<td style=\"padding: 2px 5px 2px 5px;\">v" + version + "</td>");
out.write("</tr>");}}
How to define your own content for the Welcome page and the First Steps page (new in v5.0)?
Just edit web/naviox/welcome.jsp and web/naviox/firstSteps.jsp in your project.
How to access to the View object from a custom JSP?
In our JSP we have to add the next lines:
<jsp:useBean id="context"class="org.openxava.controller.ModuleContext" scope="session"/><%String viewObject = request.getParameter("viewObject");
viewObject = (viewObject == null || viewObject.equals(""))?"xava_view":viewObject;
org.openxava.view.View view = (org.openxava.view.View) context.get(request, viewObject);System.out.println("modelo: " + view.getModelName());// Here we use view
How to generate real Excel instead of CSV in all my modules (new in v5.5)?
Moreover, in your own controllers you have to extend from TypicalRealExcel instead from Typical.
How to forward to a page in a new window without reloading the current page?
Reloading the current page is the correct behavior because in your action you could modify the view, add messages, etc. Anyways, if you want forwaring without reloading it's possible using JavaScript, in this way:
packageorg.openxava.provaox.actions;importorg.openxava.actions.*;publicclass ForwardWithoutReloadingAction extends BaseAction implements IForwardAction {publicvoid execute()throwsException{// Do something, if you want}publicboolean inNewWindow(){returnfalse;// Because we'll open the window ourselves using JavaScript}publicString getForwardURI(){return"javascript:void(window.open('/MyApplication/myurl'))";}}
Table of Contents
How to ...
How to prevent from modifying certain fields in a view?
In Update view, by default, all the fields (except the key) are modifiables.But you can declare any property of the view read only, in this way:
Or, if you are using OX3:
How to use a different view for creating and for updating?
Obiously you must define a view for creating and another for updating, thus:Or, if you are using OX3:
Now you have to refine the new action for chosing the Create view and the searching action for chosing the Update view. First, define your own controller, in your controllers.xml, thus:
And now assign this controller to your module, and define the searching action for the module. Write your module in the application.xml in this way:
And now only remains to refine the logic of your actions. For MySearchAction you write (NOTE: selected entity index values have to be captured (1) so that it might be restored (3) after the reset performed by setViewName(...) method (2)):
And for MyNewAction:
How to deactive a property for updating but not for creating?
You have to refine the new action and the searching action. First, define your own controller, in your controllers.xml, thus:And now assign this controller to your module, and define the searching action for the module, write your module in the application.xml in this way:
And now only remains to refine the logic of your actions. For MySearchAction you write:
And for MyNewAction:
How to access to a property of the model that isn't shown in the view?
From the view you can obtain only the displayed data. But it's possible, using MapFacade class to acess directly to the model.You can write in your action a code like this one:
In this way you can access to specialDiscount property although it is not displayed in the current view.
How to modify the appearance of @ReadOnly fields
By default, OpenXava will lightly shade fields that are dropdowns and those annotated with @ReadOnly. Marking a field @ReadOnly also removes the icon associated with editing. However, in my application, a requirement was that read-only fields be highlighted differently. This can be done by adding an entry into your custom.css file in the web/xava/style directory in your project as documented in the Customizing Views section.The relevant entry is:
Of course, you can put any valid css that matches your needs.
How to store user preferences (new in v3.0.2)?
Storing user preferences of your application is your business, but for your convenience you can use OpenXava to store user preferences.OpenXava uses the Java Preferences API for storing and loading user preferences, but adapted for working in a multiuser server environment. You can access to the Preferences object using the Users class of OpenXava. Just in this way:
You must call explicitly to flush() in order to store the changed preferences.
Example of basic authentication security for OX application in Tomcat
Look at this forum message.How to add your own servlets, filters, listeners or resources to your OpenXava application?
For adding your own servlets to your OX application do not modify the web.xml file, instead you can create a servlets.xml (with servlet and servlet-mapping elements), a filters.xml (with filter and filter-mapping elements), a listeners.xml (with listener elements, since v4.0.1) and a resources.xml (with resource-ref elements, since v5.4) in the WEB-INF folder.For example, if you want to add a servlet called TestServlet, just create a servlets.xml file in WEB-INF with the next content:
This fragment will be automatically inserted in web.xml when you call to deployWar or updateOX ant task.
How to create a new element directly from a @ManyToMany collection? (new in v4m4)
By default in a @ManyToMany collection the user can add existing elements to the collection, however he cannot create new ones. Fortunately, you can add this functionality using the ManyToMany.new action (included in OpenXava) as list action for your collection. As following:How to change schema, locale and user using url parameters (new in v4m4)
You can change default schema, current locale or current user through web parameters by including the controller UrlParameters(1). For example in application.xml you add the controller:The url for invoking the module now can contain the schema parameter.
http://localhost:8080/MyApplication/xava/module?application=MyApplication&module=MyModule&schema=companyAor the locale parameter:http://localhost:8080/MyApplication/xava/module?application=MyApplication&module=MyModule&locale=esor the user parameter (it will be stored in session's attribute xava.user):http://localhost:8080/MyApplication/xava/module?application=MyApplication&module=MyModule&user=theUserThey are not exclusive, you can use any combination of them.How to add a second collection in a report
Modify your .jrxml, to add a subreport in one of the available bands (not the details ones, obviously). You can do that easily from the XML perspective of iReport.Also add matching parameters at the top of the file, below your parameters.
You will have to design a new report in iReport describing the fields of the collection you want to add. Generally a columnHeader and a detail band are enough
In your report action, fill in the new parameters:
1- Replace by the path to your subreport.
2- Any Collection is valid. The fields of the subreport refer to the properties of the collection members.
How to define a JavaScript-based action?
One use case could be, for example, to be able to click on a button (in a 'detail' page) to execute some custom JavaScript code.To do so, you need OpenXava version N>=4, and you have to write a IForwardAction whose uri stars with "javascript:"
public class GoToGoogleAction implements IForwardAction { public String getForwardURI() { return "javascript:top.location=\"http://www.google.fr\""; } public boolean inNewWindow() { return false; } ... }Other IForwardAction methods could remain empty, or auto-generated if you like.Since v5.9 you can implements IPostJavaScriptAction, that after the regular action execution executes your JavaScript code:
public class MyJavaScriptAction extends BaseAction implements IJavaScriptPostAction { public void execute() throws Exception { addMessage("Hello, I'm Java"); } public String getPostJavaScript() { return "alert('Hello, I am JavaScript')"; } }Unlike IForwardAction to javascript: in IPostJavaScriptAction the JavaScript is executed when the view is completely updated after regular Java execution.How to remove PDF + Excel export actions in GUI ?
These actions are defined by the 'Print' controller. All controllers inherits these actions from the default controller, named 'Typical', that extends the 'Print' controller:So, these actions are available by default to all controllers.
One way to remove them for all GUI is to redefine the 'Typical' controller in controllers.xml:
But, still, these PDF + Excel export actions remain for collections within a business class. It's due to the 'DefaultListActionsForCollections' controller that extends the 'Print' controller too:
So, in order to remove these PDF + Excel export actions always for embedded collections is to redefine the 'DefaultListActionsForCollections' controller:
And then, no PDF + Excel export action appear.
How to modify the parameters of the default reports?
We can change the parameters of the default report by code. In this case we change the organization name:By default this organization name is collected from 'xava.organization' value in the i18n files, but we modify it to that this organization name is collected from a variable value.
Just create a new class that implements to IReportParametersProvider and add the code that you need to the 'getOrganization()' method:
To finish add in your 'xava.properties' file a new line with the class to use:
How to generate HTML reports?
One option is to forward to a JSP that generates the HTML report, you can do it by means of IForwardAction. Another option is using the SimpleHTMLReportAction action (since v4.3) that allows you to work with simple HTML templates.How to generate several reports from a single action?
Just extend your action from JasperMultipleReportBaseAction (new in v4.3). For an example look at InvoiceTwoReportsAction of OpenXavaTest.How to merge multiple reports in one PDF?
Just extend your action from JasperConcatReportBaseAction (new in v5.0). Useful when you need to concatenate several reports with different page formats (landscape, portrait). There is an example at MovieReportAction of OpenXavaTest.How to add your own portlets to your OpenXava application (new in v4.6)?
For adding your own portlets to your OX application do not modify the portlet.xml file, instead you can create a portlet-ext.xml (with portlet elements) and a liferay-display-ext.xml (with portlet elements) in the WEB-INF folder.For example, if you want to add a portlet called VersionPortlet, just create a portlet-ext.xml file in WEB-INF with the next content:
If you are using Liferay you can optionally create the liferay-display-ext.xml file to add entries to liferay-display.xml file. So, for the above portlet you can write a liferay-display-ext.xml with the next content:
<portlet id="Version" />This fragment will be automatically inserted in liferay-display.xml when you call to generatePortlets ant task.Moreover, you have to write the resorce files, in this case you have to write Version_ca.properties, Version_es.properties, Version_en.properties and Version_fr.properties. Here there is a example for Version_en.properties:
And, of course, you need to write the code for your portlet, in this case:
How to define your own content for the Welcome page and the First Steps page (new in v5.0)?
Just edit web/naviox/welcome.jsp and web/naviox/firstSteps.jsp in your project.How to access to the View object from a custom JSP?
In our JSP we have to add the next lines:How to generate real Excel instead of CSV in all my modules (new in v5.5)?
Add this to your application.xml:Moreover, in your own controllers you have to extend from TypicalRealExcel instead from Typical.
How to forward to a page in a new window without reloading the current page?
Reloading the current page is the correct behavior because in your action you could modify the view, add messages, etc. Anyways, if you want forwaring without reloading it's possible using JavaScript, in this way: